/**
 * @class   wosh::Interpreter
 * @brief   The class holds information about a generic interpreter service,
 *          defined by wosh::interfaces::services::InterpreterService
 *
 * @see     wosh::services::CommunicatorManagerBundle
 ****************************************************************************
 * @version $Id: Interpreter.h 2863 2010-08-07 04:28:58Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_Interpreter_H__
 #define __WOSH_Core_Interpreter_H__

 #include <woshDefs.h>
 #include <core/Object.h>
 #include <core/SharedObject.h>
 #include <core/InterfacesProvider.h>
 #include <core/Notification.h>
 #include <core/Communicator.h>
 #include <core/DataModels.h>


namespace wosh {

class Interpreter : public Object
 {
	WOSH_SERIALIZABLE(wosh::Interpreter)

	public:
		/**
		 * @brief  Empty constructor.
		 */
		Interpreter() : Object() {
			Object::setName( "Interpreter" );
			this->inputTypes = Notification::TYPE_UNKNOWN;
			this->outputTypes = Notification::TYPE_UNKNOWN;
			this->inputProtocols = Notification::PROTOCOL_UNKNOWN;
			this->outputProtocols = Notification::PROTOCOL_UNKNOWN;
			setSeen();
		 }
		/**
		 * @brief  Copy constructor.
		 * @param m [in] the source object to be copied
		 */
		Interpreter( const Interpreter& m ) : Object() {
			*this = m;
		 }
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~Interpreter() { }


	public:

		virtual void setName( const std::string& value ) {
			Object::setName(value);
			bool glob = Object::getURI().isGlobal();
			if ( glob )
				Object::getURI().unRegisterGlobal();
			Object::getURI().setName( Object::getName() );
			if ( glob )
				Object::getURI().registerGlobal();
		 }

		using Object::setURI;

		inline void setInputTypes( int value )						{ this->inputTypes = value; }
		inline void setOutputTypes( int value )						{ this->outputTypes = value; }

		inline void setInputProtocols( int value )					{ this->inputProtocols = value; }
		inline void setOutputProtocols( int value )					{ this->outputProtocols = value; }

	public:

		inline int getInputTypes() const							{ return this->inputTypes; }
		inline int getOutputTypes() const							{ return this->outputTypes; }

		inline int getInputProtocols() const						{ return this->inputProtocols; }
		inline int getOutputProtocols() const						{ return this->outputProtocols; }

		inline const std::vector<std::string>& getInputLanguages() const	{ return this->inputLanguages; }
		inline std::vector<std::string>& getInputLanguages()				{ return this->inputLanguages; }
		inline std::string getInputLanguagesStr() const						{ return Utilities::joinVector(this->inputLanguages, ""); }

		inline const std::vector<std::string>& getOutputLanguages() const	{ return this->outputLanguages; }
		inline std::vector<std::string>& getOutputLanguages()				{ return this->outputLanguages; }
		inline std::string getOutputLanguagesStr() const					{ return Utilities::joinVector(this->outputLanguages, ""); }


		inline void setSeen()										{ this->timestamp = Utilities::std_time(); }
		inline long getSeen() const									{ return this->timestamp; }

		inline const InterfacesProvider& getInterfaces() const		{ return this->Interfaces; }
		inline InterfacesProvider& getInterfaces()					{ return this->Interfaces; }


		static DataFieldCollector<Interpreter>* getDataFields() {
			DataFieldCollector<Interpreter>* fields = new DataFieldCollector<Interpreter>();
			fields->add<const URI&,URI>(&Interpreter::getURI, "URI", 0);
			fields->add<long,Variant_DT>(&Interpreter::getSeen, "SeenAt", 1);
			fields->add<int,Variant>(&Interpreter::getInputTypes, "InType", 2);
			fields->add<int,Variant>(&Interpreter::getOutputTypes, "OutType", 3);
			fields->add<int,Variant>(&Interpreter::getInputProtocols, "InProto", 4);
			fields->add<int,Variant>(&Interpreter::getOutputProtocols, "OutProto", 5);
			fields->add<std::string, Variant>(&Interpreter::getInputLanguagesStr, "InLangs", 6);
			fields->add<std::string, Variant>(&Interpreter::getOutputLanguagesStr, "OutLangs", 7);
			return fields;
		 }


	protected:

		virtual Interpreter& operator=(const Interpreter& m) {
			if (this == &m) return *this; // same object?
			(Object&)*this = (const Object&)m;
			this->timestamp = m.timestamp;
			this->Interfaces = m.Interfaces;
			this->inputTypes = m.inputTypes;
			this->outputTypes = m.outputTypes;
			this->inputProtocols = m.inputProtocols;
			this->outputProtocols = m.outputProtocols;
			this->inputLanguages = m.inputLanguages;
			this->outputLanguages = m.outputLanguages;
			return *this;
		 }

		virtual bool operator==(const Interpreter &other) const {
			(void)other;
			return false;
		 }

		virtual bool operator!=(const Interpreter &other) const	{ return !(*this == other);  }

//@}
/** @name Serialization interface
 * @{
 ******************************************************************************/
	public:
		virtual std::string toString() const	{ return ""; }
		virtual bool updateHash( DataHashContext* hash_context ) const {
			if ( hash_context == NULL ) return false;
			bool ret = Object::updateHash( hash_context );
			ret = hash_context->update( this->timestamp ) & ret;
			ret = this->Interfaces.updateHash( hash_context ) & ret;
			ret = hash_context->update( this->inputTypes ) & ret;
			ret = hash_context->update( this->outputTypes ) & ret;
			ret = hash_context->update( this->inputProtocols ) & ret;
			ret = hash_context->update( this->outputProtocols ) & ret;
			ret = hash_context->update( this->inputLanguages ) & ret;
			ret = hash_context->update( this->outputLanguages ) & ret;
			return ret;
		 }
//@}
	protected:
		long timestamp;					///< last seen (epoch) of real object
		InterfacesProvider Interfaces;	///< implemented interfaces
		int inputTypes;
		int outputTypes;
		int inputProtocols;
		int outputProtocols;
		std::vector<std::string> inputLanguages;
		std::vector<std::string> outputLanguages;


}; // class def

}; // namespace wosh

#endif //__WOSH_Core_Interpreter_H__
